EnsureSConsVersion( 1, 1, 0 )
  
import platform
import os
import re
from os.path import join, dirname, abspath

root_dir = dirname(File('SConstruct').rfile().abspath)
driver_include = join(root_dir, 'ext')
class_include = join(root_dir, 'ext/class')
client_include = join(root_dir, '../../SequoiaDB/engine/include')
common_include_dir = join(root_dir, '../../SequoiaDB/engine/client')
bson_include_dir = join(root_dir, '../../SequoiaDB/engine/bson')
boost_dir = join(root_dir, '../../thirdparty/boost')
boost_lib_dir = join(boost_dir, 'lib')
ssl_dir = join(root_dir, '../../thirdparty/crypto/openssl-1.0.1c')
ssl_include = join(ssl_dir, 'include')
ssl_lib_dir = join(ssl_dir, 'lib')

options = {}
options_topass = {}

def GuessOS():
  id = platform.system()
  if id == 'Linux':
    return 'linux'
  elif id == 'Windows' or id == 'Microsoft':
    return 'win32'
  else:
    return None


def GuessArch():
  id = platform.machine()
  id = id.lower()
  if (not id) or (not re.match('(x|i[3-6])86$', id) is None):
    return 'ia32'
  elif id == 'i86pc':
    return 'ia32'
  elif id == 'x86_64':
    return 'ia64'
  elif id == 'amd64':
    return 'ia64'
  elif id == 'ppc64' :
    return 'ppc64'
  elif id == 'ppc64le' :
    return 'ppc64le'  
  else:
    return None

def GuessVer():
    id = platform.uname()[2]
    return id

guess_os = GuessOS()
guess_arch = GuessArch()
guess_ver = GuessVer()

def add_option( name, help , nargs , contibutesToVariantDir , dest=None ):

    if dest is None:
        dest = name

    AddOption( "--" + name , 
               dest=dest,
               type="string",
               nargs=nargs,
               action="store",
               help=help )

    options[name] = { "help" : help ,
                      "nargs" : nargs , 
                      "contibutesToVariantDir" : contibutesToVariantDir ,
                      "dest" : dest } 

def get_option( name ):
    return GetOption( name )

def _has_option( name ):
    x = get_option( name )
    if x is None:
        return False

    if x == False:
        return False

    if x == "":
        return False

    return True

def has_option( name ):
    x = _has_option(name)

    if name not in options_topass:
        # if someone already set this, don't overwrite
        options_topass[name] = x

    return x

def get_variant_dir():

    a = []

    for name in options:
        o = options[name]
        if not has_option( o["dest"] ):
            continue
        if not o["contibutesToVariantDir"]:
            continue

        if o["nargs"] == 0:
            a.append( name )
        else:
            x = get_option( name )
            x = re.sub( "[,\\\\/]" , "_" , x )
            a.append( name + "_" + x )

    s = "#build/${PYSYSPLATFORM}/"

    if len(a) > 0:
        a.sort()
        s += "/".join( a ) + "/"
    else:
        s += "normal/"
    return s

add_option( "test", "build test program" , 0 , True , "testpro" )
add_option( "clienttest", "build test program" , 0 , True , "clienttestpro" )
add_option( "dd", "debug build no optimization, additional debug logging, etc..." , 0 , True , "debugBuildAndLogging" )
add_option( "phpversion", "debug build no optimization, additional debug logging, etc..." , 1 , False , "phpEdition" )


debugBuild = has_option( "debugBuildAndLogging" )
testBuild = has_option( "testpro" )
clienttestBuild = has_option( "clienttestpro" )

phpedition = ""
if testBuild or clienttestBuild :
    print "build test program file ! "
else:
    if ( has_option( "phpEdition" ) ) :
       sys_os = GuessOS()
       phpedition = get_option ( 'phpEdition' )
       main_dir = join(root_dir,'../../thirdparty/php/' + sys_os + '/php-' + phpedition + '/main')
       Zend_dir = join(root_dir,'../../thirdparty/php/' + sys_os + '/php-' + phpedition + '/Zend')
       TSRM_dir = join(root_dir, '../../thirdparty/php/' + sys_os + '/php-' + phpedition + '/TSRM')
       regex_dir = join(root_dir,'../../thirdparty/php/' + sys_os + '/php-' + phpedition + '/regex')
       source_dir = join(root_dir,'../../thirdparty/php/' + sys_os + '/php-' + phpedition)
       lib_dir = join(root_dir, '../../thirdparty/php/' + sys_os + '/php-' + phpedition + '/lib')
       ext_dir = join(root_dir, '../../thirdparty/php/' + sys_os + '/php-' + phpedition)
    else:
       print "Please input the version information,For example: 'scons --phpversion=5.3.10' "
       exit(1)

variantDir = get_variant_dir()
env = Environment( BUILD_DIR=variantDir )

if phpedition.split( '.' )[0] == '7':
   env.Append ( CPPDEFINES=[ "__PHP7__", "ZEND_ENABLE_LONG64" ] )

env.Append ( CPPDEFINES=[ "SDB_DLL_BUILD" ] )
env.Append ( CPPDEFINES=[ "SDB_CLIENT" ] )
env.Append ( CPPDEFINES=[ "SDB_SSL" ] )
if guess_os == "win32":

    if guess_ver == "10":
        env['ENV'] = dict(os.environ)
        if guess_arch == "ia64":
            env['ENV']['PATH'] = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64;" + env['ENV']['PATH']
        else:
            env['ENV']['PATH'] = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin;" + env['ENV']['PATH']

    # check VC compiler
    for pathdir in env['ENV']['PATH'].split(os.pathsep):
        if os.path.exists(os.path.join(pathdir, 'cl.exe')):
            print( "found visual studio at " + pathdir )
            break
        else:
            #use current environment
            env['ENV'] = dict(os.environ)

    env.Append( CPPDEFINES=["_CRT_SECURE_NO_WARNINGS", "ZEND_WIN32_FORCE_INLINE", "HAVE_SOCKLEN_T","ZEND_DEBUG=0", "WIN32", "_MBCS","_USRDLL","_EXPORTS","COMPILE_DL_SEQUOIADB","ZTS=1","ZEND_WIN32","PHP_WIN32","HAVE_SEQUOIADB=1"] )
    if guess_arch == "ia64":
        env.Append( CPPDEFINES=[ "_WIN64" ] )

    if testBuild or clienttestBuild :
        winLibString = "ws2_32.lib kernel32.lib advapi32.lib psapi.lib dbghelp.lib user32.lib gdi32.lib winspool.lib comdlg32.lib sdbcpp.lib"
    else:
        if phpedition.split( '.' )[0] == '7':
            winLibString = "ws2_32.lib kernel32.lib advapi32.lib psapi.lib dbghelp.lib user32.lib gdi32.lib winspool.lib comdlg32.lib php7ts.lib ssleay32.lib libeay32.lib"
        else:
            winLibString = "ws2_32.lib kernel32.lib advapi32.lib psapi.lib dbghelp.lib user32.lib gdi32.lib winspool.lib comdlg32.lib php5ts.lib ssleay32.lib libeay32.lib"
        if guess_arch == "ia64":
            env.Append( LIBPATH=[join(lib_dir,'win64')] )
            env.Append( LIBPATH=[join(ssl_lib_dir,'win64')] )
        else:
            env.Append( LIBPATH=[join(lib_dir,'win32')] )
            env.Append( CPPDEFINES=[ "_USE_32BIT_TIME_T=1"])
            env.Append( LIBPATH=[join(boost_lib_dir,'win32')] )
            env.Append( LIBPATH=[join(ssl_lib_dir,'win32')] )

    if guess_ver == "10":
        env.Append( CPPPATH=[ "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
                              "C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt",
                              "C:/Program Files (x86)/Windows Kits/8.1/Include/um",
                              "C:/Program Files (x86)/Windows Kits/8.1/Include/shared",
                              "C:/Program Files (x86)/Windows Kits/8.1/Include/winrt" ] )
        if guess_arch == "ia64":
            env.Append( LIBPATH=[ "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/lib/amd64",
                                  "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt/x64",
                                  "C:/Program Files (x86)/Windows Kits/8.1/Lib/winv6.3/um/x64",
                                  "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/Lib/um/x64" ] )
        else:
            env.Append( LIBPATH=[ "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/lib",
                                  "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt/x86",
                                  "C:/Program Files (x86)/Windows Kits/8.1/Lib/winv6.3/um/x86",
                                  "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/Lib/um/x86" ] )

    env.Append( LIBS=Split(winLibString) )
    env.Append( CPPDEFINES=[ "_CRT_RAND_S" ] )
    env.Append( CPPDEFINES=[ "UNICODE" ] )
    env.Append( CPPFLAGS=" /EHsc /W3 " )
    if debugBuild:
        env.Append( CPPFLAGS=" /RTC1 /MDd /Z7 /errorReport:none " )
        env.Append( LINKFLAGS=" /debug " )
        env.Append( CPPFLAGS=" /Od " )
    else:
        env.Append( CPPDEFINES=[ "NDEBUG" ] )
        env.Append( CPPFLAGS= " /O2 /Gy " )
        env.Append( CPPFLAGS= " /MT /Zi /errorReport:none " )
        env.Append( CPPFLAGS= " /GL " )
        env.Append( LINKFLAGS=" /LTCG " )

elif guess_os == "linux":

    env.Execute(Copy(main_dir,join(root_dir, '../../thirdparty/php/linux/forlinux/main/build-defs.h')))
    env.Execute(Copy(main_dir,join(root_dir, '../../thirdparty/php/linux/forlinux/main/php_config.h')))
    env.Execute(Copy(TSRM_dir,join(root_dir, '../../thirdparty/php/linux/forlinux/TSRM/tsrm_config.h')))
    env.Execute(Copy(Zend_dir,join(root_dir, '../../thirdparty/php/linux/forlinux/Zend/zend_config.h')))

    env.Append( CPPDEFINES=["PHP_ATOM_INC","HAVE_CONFIG_H","PIC"])
    env['ENV']['HOME']=os.environ['HOME']
    env['ENV']['TERM']=os.environ['TERM']
    env.Append( CPPFLAGS="-ggdb" )
    if guess_arch == "ia64":
        env.Append( LIBPATH="/usr/lib64")
        env.Append( LIBPATH="/lib64")
        env.Append( LIBPATH=[join(boost_lib_dir,'linux64')] )
        env.Append( LIBPATH=[join(ssl_lib_dir,'linux64')] )
    elif guess_arch == "ia32":
        env.Append( LIBPATH="/usr/lib")
        env.Append( LIBPATH="/lib")
        env.Append( LIBPATH=[join(boost_lib_dir,'linux32')] )
        env.Append( LIBPATH=[join(ssl_lib_dir,'linux32')] )
    elif guess_arch == 'ppc64':
        if phpedition.split( '.' )[0] == '7':
            env.Append ( CPPDEFINES=[ "WORDS_BIGENDIAN" ] )
        env.Append( CPPDEFINES=[ "SDB_BIG_ENDIAN" ] )
        env.Append( LIBPATH="/usr/lib64")
        env.Append( LIBPATH="/lib64")
        env.Append( LIBPATH=[join(boost_lib_dir,'ppclinux64')] )
        env.Append( LIBPATH=[join(ssl_lib_dir,'ppclinux64')] )
    elif guess_arch == 'ppc64le':
        env.Append( CPPDEFINES=[ "SDB_LITTLE_ENDIAN" ] )
        env.Append( LIBPATH="/usr/lib64")
        env.Append( LIBPATH="/lib64")
        env.Append( LIBPATH=[join(boost_lib_dir,'ppclelinux64')] )
        env.Append( LIBPATH=[join(ssl_lib_dir,'ppclelinux64')] )
    if testBuild or clienttestBuild :
       winLibString = "sdbcpp"
       env.Append( LIBS=Split(winLibString) )
    else:
       env.Append( LIBS=['ssl'] )
       env.Append( LIBS=['crypto'] )
    if debugBuild:
        env.Append( CPPFLAGS=" -O0 -fstack-protector")
        env['ENV']['GLIBCXX_FORCE_NEW']=1
    else:
        env.Append( CPPFLAGS=" -O3")
if testBuild or clienttestBuild :
    client_lib_dir = join(root_dir,'../../client/CPP/lib')
    env.Append( LIBPATH=[client_lib_dir] )
    ext_dir = join(root_dir, 'ext')
    env.Append( CPPPATH=[root_dir,client_include,boost_dir]  )
else:
    env.Append( CPPPATH=[main_dir, TSRM_dir, Zend_dir, root_dir, driver_include, class_include, source_dir,ext_dir,client_include,boost_dir,common_include_dir,bson_include_dir,ssl_include]  )

Export("env")
Export("root_dir")
Export("testBuild")
Export("clienttestBuild")
Export("phpedition")
env.SConscript( 'SConscript', variant_dir=variantDir, duplicate=False )
